package org.dolphin.service.impl;

import java.util.List;
import javax.annotation.Resource;
import org.dolphin.base.bean.CityVO;
import org.dolphin.base.bean.CustomerVO;
import org.dolphin.base.bean.FlatCustomerVO;
import org.dolphin.base.bean.RegionVO;
import org.dolphin.dao.CustomerDao;
import org.dolphin.entity.customer.Customer;
import org.dolphin.entity.district.Address;
import org.dolphin.entity.district.City;
import org.dolphin.entity.district.Region;
import org.dolphin.service.CustomerService;
import org.dolphin.util.Pagination;
import org.dolphin.service.base.UserProfileHelper;
import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service(value = "customerService")
@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
public class CustomerServiceImpl implements CustomerService {
  @Autowired(required = true)
  private CustomerDao customerDao;
  @Resource(name = "messageResource")
  private MessageSource messageSource;

  @Transactional(readOnly = false)
  @Override
  public void createCustomer(Customer customer) {
    String alias = customer.getAlias();
    Customer c = customerDao.getCustomer(alias);
    if (c != null) {
      String field = messageSource.getMessage("field.customer.alias", null,
          UserProfileHelper.getUserLocale());
      String error = messageSource.getMessage("error.not.available", new Object[] {field},
          UserProfileHelper.getUserLocale());
      throw new IllegalArgumentException(error);
    }
    customerDao.saveCustomer(customer);
  }

  @Override
  public Customer fetchCustomer(Long id) {
    Customer customer = customerDao.fetchCustomer(id, false);
    return customer;
  }

  @Override
  public CustomerVO getCustomer(Long id) {
    Customer customer = customerDao.fetchCustomer(id, true);
    CustomerVO vo = toCustomerVO(customer);
    return vo;
  }

  @Override
  public List<FlatCustomerVO> getCustomers(int page, int rows, List<Order> orders) {
    page = page > 0 ? page : 1;
    int startIndex = Pagination.calculateStartIndex(page, rows);
    List<FlatCustomerVO> customers = customerDao.getCustomers(startIndex, rows, orders);
    return customers;
  }

  @Override
  public Long getCustomersCount() {
    Long count = customerDao.getCustomersCount();
    return count;
  }

  protected CustomerVO toCustomerVO(Customer customer) {
    Address address = customer.getAddress();
    City city = address.getCity();
    Region region = city.getRegion();

    CityVO cityVO = new CityVO();
    RegionVO regionVO = new RegionVO();
    CustomerVO vo = new CustomerVO();

    vo.setFirstname(customer.getFirstname());
    vo.setLastname(customer.getLastname());
    vo.setAlias(customer.getAlias());
    vo.setMobile(customer.getMobile());
    vo.setPhone(customer.getPhone());
    vo.setEmail(customer.getEmail());
    vo.setFax(customer.getFax());
    vo.setStreet(address.getStreet());
    vo.setPostalCode(address.getPostalCode());
    vo.setVersion(customer.getVersion());
    vo.setCity(cityVO);
    vo.setRegion(regionVO);
    cityVO.setId(city.getId());
    cityVO.setName(city.getName());
    regionVO.setId(region.getId());
    regionVO.setName(region.getName());
    return vo;
  }

  @Transactional(readOnly = false)
  @Override
  public void updateCustomer(Customer customer) {
    String alias = customer.getAlias();
    String id = customer.getId();
    Customer c = customerDao.getCustomer(alias, id);
    if (c != null) {
      String field = messageSource.getMessage("field.customer.alias", null,
          UserProfileHelper.getUserLocale());
      String error = messageSource.getMessage("error.not.available", new Object[] {field},
          UserProfileHelper.getUserLocale());
      throw new IllegalArgumentException(error);
    }
    customerDao.updateCustomer(customer);
  }
}
